﻿using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
using System.Runtime.InteropServices;

namespace Guru.Utilities
{
    public class ImageExtensions
    {
        public static Image DrawReflection(Image img, Color toBG)
        {
            //This is the static function that generates the reflection...
            //Added height from the original height of the image.
            int height = img.Height + img.Height / 2;
            //A new bitmap.
            Bitmap bmp = new Bitmap(img.Width, height, PixelFormat.Format64bppPArgb);
            //The Brush that generates the fading effect to a specific color of your background.
            Brush brsh = new LinearGradientBrush(new Rectangle(0, 0, img.Width + 10, height), Color.Transparent, toBG, LinearGradientMode.Vertical);
            bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution); //Sets the new 
            //A graphics to be generated. From an image (here, the new Bitmap we've created (BMP)).
            using (Graphics grfx = Graphics.FromImage(bmp))
            {
                //Generates a bitmap from the original image (img).
                Bitmap bm = (Bitmap)img;
                //Draws the generated 
                grfx.DrawImage(bm, 0, 0, img.Width, img.Height);
                ////Generates a bitmap again 
                Bitmap bm1 = (Bitmap)img;
                //Flips and rotates the 
                bm1.RotateFlip(RotateFlipType.Rotate180FlipX);
                //Draws (bm1) below (bm) so it serves 
                grfx.DrawImage(bm1, 0, img.Height);
                ////A new rectangle 
                Rectangle rt = new Rectangle(0, img.Height, img.Width, img.Height / 2);
                //Brushes the gradient on (rt).
                grfx.FillRectangle(brsh, rt);
            }
            return bmp;
        }
        public static Image ReadFromFile(string fullPath)
        {
            if (!File.Exists(fullPath))
            {
                return null;
            }
            else
            {
                Image image = Image.FromFile(fullPath);
                Bitmap bitmap = new Bitmap(image);
                Image indexedImage = CreateIndexedImage(bitmap) as Image;
                image.Dispose();
                return indexedImage;
            }
        }
        public static Bitmap CreateIndexedImage(Bitmap bmp)
        {
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);

            int byteCount = bmpData.Stride * bmpData.Height;
            byte[] bytes = new byte[byteCount];

            Marshal.Copy(bmpData.Scan0, bytes, 0, byteCount);
            bmp.UnlockBits(bmpData);

            Bitmap bmpNew = new Bitmap(bmp.Width, bmp.Height);
            BitmapData bmpData1 = bmpNew.LockBits(new Rectangle(new Point(), bmpNew.Size), ImageLockMode.ReadWrite, bmp.PixelFormat);
            Marshal.Copy(bytes, 0, bmpData1.Scan0, bytes.Length);
            bmpNew.UnlockBits(bmpData1);
            bmp.Dispose();
            return bmpNew;

        }
        public static void SaveToPngImage(string path, Bitmap img, long quality)
        {
            Save(path, img, quality, "image/png");
        }
        public static void SaveToJpgImage(string path, Bitmap img, long quality)
        {
            Save(path, img, quality, "image/jpeg");
        }
        public static void SaveToGifImage(string path, Bitmap img, long quality)
        {
            Save(path, img, quality, "image/gif");
        }
        public static void Save(string path, Bitmap img, long quality, string mimeType)
        {
            EncoderParameter qualityParam
                  = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)quality);
            //Copy an image from orginal image           
            Bitmap btnNew = CreateIndexedImage(img);
            ImageCodecInfo pngCodec = GetEncoderInfo(mimeType);
            EncoderParameters encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = qualityParam;
            //Remove readonly to resolve GDI+ error
            if (File.Exists(path))
            {
                File.SetAttributes(path, FileAttributes.Normal);
            }
            btnNew.Save(path, pngCodec, encoderParams);
            btnNew.Dispose();
        }
        public static ImageCodecInfo GetEncoderInfo(string mimeType)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

            for (int i = 0; i < codecs.Length; i++)
            {
                if (codecs[i].MimeType == mimeType)
                    return codecs[i];
            }
            return null;
        }
    }
}
